package bsuir.magistrate.projects.service;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Service;

import bsuir.magistrate.projects.core.BinFile;

@Service
public class BinFileReaderService {

	public static int currentPosition = -1;

	public BinFile getBinFileProperties(File file) throws IOException {
		byte[] bytes = null;
		bytes = getBytesOfFile(file);

		// Order is crucial (DO NOT CHANGE ORDER)!!!
		BinFile binFile = new BinFile();
		binFile.setFileSignature(getFileSignature(bytes));
		binFile.setNumberOfChanels(getIntValue(bytes));
		binFile.setSizeOfSelectionsForOneChannel(getIntValue(bytes));
		binFile.setNumberOfSpectralLines(getIntValue(bytes));
		binFile.setCutOffFequency(getIntValue(bytes));
		binFile.setFrequencyResolution(getFloatValue(bytes));
		binFile.setDataBlockReceptionTime(getFloatValue(bytes));
		binFile.setSignalReceptionTime(getIntValue(bytes));
		binFile.setSignalReceptionTime(getIntValue(bytes));
		binFile.setNumberOfAcceptedBlocksUser(getIntValue(bytes));
		binFile.setDataSize(getIntValue(bytes));
		binFile.setNumberOfAcceptedBlocksSystem(getIntValue(bytes));
		binFile.setMaxDataValue(getFloatValue(bytes));
		binFile.setMinDataValue(getFloatValue(bytes));
		binFile.setDiscretSignalValues(getFloatList(bytes));

		return binFile;

	}

	private static byte[] getBytesOfFile(File file) throws IOException {
		byte[] bytes;

		int size = (int) file.length();// It gives the length of the file.

		bytes = new byte[size];
		DataInputStream dis = new DataInputStream(new FileInputStream(file));
		int read = 0;
		int numRead = 0;
		while (read < bytes.length
				&& (numRead = dis.read(bytes, read, bytes.length - read)) >= 0) {
			read = read + numRead;
		}

		// Ensure all the bytes have been read in
		if (read < bytes.length) {
			System.out.println("Could not completely read: " + file.getName());
		}

		return bytes;
	}

	public static String getFileSignature(byte[] bytes) {
		return CharBuffer.wrap(new char[] { //
				(char) bytes[++currentPosition], //
						(char) bytes[++currentPosition], //
						(char) bytes[++currentPosition], //
						(char) bytes[++currentPosition] }).toString();
	}

	public static int getIntValue(byte[] bytes) {
		return ByteBuffer.wrap(new byte[] {//
				bytes[++currentPosition],//
						bytes[++currentPosition],//
						bytes[++currentPosition],//
						bytes[++currentPosition] })
				.order(ByteOrder.LITTLE_ENDIAN).getInt();
	}

	public static float getFloatValue(byte[] bytes) {
		return ByteBuffer.wrap(new byte[] {//
				bytes[++currentPosition],//
						bytes[++currentPosition],//
						bytes[++currentPosition],//
						bytes[++currentPosition] })
				.order(ByteOrder.LITTLE_ENDIAN).getFloat();
	}

	public static List<Float> getFloatList(byte[] bytes) {
		List<Float> list = new ArrayList<Float>();
		while (bytes.length - currentPosition >= 4) {
			list.add(getFloatValue(bytes));
		}
		return list;
	}
}
